package woaini.wind.bot.gitlab.service;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.experimental.UtilityClass;
import woaini.wind.bot.core.event.segment.Messages;
import woaini.wind.bot.core.internal.Internal;
import woaini.wind.bot.core.manager.BotManager;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Git Lab Web Hook 处理程序
 *
 * @see woaini.wind.bot.gitlab.service.GitLabWebHookHandler
 * @author yefeng {@date 2025-01-03 14:48:49}
 */
@UtilityClass
public class GitLabWebHookHandler {

  public static final String DEFAULT_VALUE = "1";

  /**
   * @see Map<String, Consumer<JSONObject>> Event Hander 处理器
   */
  public static final Map<String, Consumer<JSONObject>> EVENT_HANDER_MAP;

  public static final List<String> SHOW_STATUS_LIST =
      CollUtil.newArrayList("pending", "running", "success", "failed");

  /**
   * @see TimedCache<String, String> 定时缓存 默认监听缓存时间为1小时 也就是标签至少这个时间内
   */
  public static TimedCache<String, String> TAG_HOOKS_CACHE =
      CacheUtil.newTimedCache(DateUnit.HOUR.getMillis());

  static {
    EVENT_HANDER_MAP = new HashMap<>();
    EVENT_HANDER_MAP.put("pipeline", GitLabWebHookHandler::pipelineHandler);
  }

  public void handler(JSONObject event) {
    // 获取上报类型
    String eventType = event.getString("object_kind");
    // 获取是否存在处理程序
    Consumer<JSONObject> handler = EVENT_HANDER_MAP.get(eventType);
    if (handler == null) {
      return;
    }
    handler.accept(event);
  }

  public void addHookTag(String tag){
    TAG_HOOKS_CACHE.put(tag,DEFAULT_VALUE);
  }

  /**
   * 流水线处理程序
   *
   * @param jsonObject JSON 对象
   * @author yefeng {@date 2025-01-03 14:54:08}
   * @since 1.0
   */
  public void pipelineHandler(JSONObject jsonObject) {
    // 获取标签信息 如果不是hook的标签直接返回
    String tag = (String) jsonObject.getByPath("$.object_attributes.ref");
    //是否监听tag
    if (!StrUtil.equals(TAG_HOOKS_CACHE.get(tag,false),DEFAULT_VALUE)) {
      return;
    }
    Integer id = (Integer) jsonObject.getByPath("$.object_attributes.id");
    String status = (String) jsonObject.getByPath("$.object_attributes.status");
    String pathName = (String) jsonObject.getByPath("$.project.path_with_namespace");

    if (!SHOW_STATUS_LIST.contains(status)) {
      return;
    }
    // 获取步骤列表
    List<String> stages = (List<String>) jsonObject.getByPath("$.object_attributes.stages");

    // 获取状态集合
    JSONArray builds = jsonObject.getJSONArray("builds");

    Map<String, List<String>> stageStatusMap = new HashMap<>();
    for (String stage : stages) {
      stageStatusMap.put(stage, new ArrayList<>());
    }

    for (int i = 0; i < builds.size(); i++) {
      JSONObject build = builds.getJSONObject(i);
      // 获取stage
      String stage = build.getString("stage");
      String subStatus = build.getString("status");
      // 获取步骤是否存在
      List<String> subStatusList = stageStatusMap.get(stage);
      subStatusList.add(subStatus);
    }

    StringBuilder sb = new StringBuilder();
    sb.append(STR."任务日志(\{pathName})\n");
    sb.append("触发流水线id:").append(id).append("\n");
    sb.append("tag:").append(tag).append("\n");
    sb.append("流水线总状态:").append(status).append("\n");
    // 子状态信息组装
    stageStatusMap.forEach(
        (stage, subStatusList) -> {
          sb.append("阶段:").append(stage).append("\n");
          // 统计每个状态的数量

          subStatusList.stream()
              .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
              .forEach(
                  (subStatus, count) -> {
                    sb.append("\t状态:").append(subStatus).append(" 数量:").append(count).append("\n");
                  });
        });
    //发送风儿群
    //微信群的
    Internal internal = BotManager.getBot("wxid_v85yukiizzag22", "wx").internal();
    internal.sendGroupMessage("48924592493@chatroom", Messages.builder().text(sb.toString()));
    System.out.println(sb);
  }
}
